package com.asen.commons.core.meta.loader;

import com.asen.commons.annotation.EntityModel;
import com.asen.commons.annotation.QueryResultProcessor;
import com.asen.commons.core.jdbc.result.ResultProcessor;
import com.asen.commons.core.jdbc.result.ResultProcessorRegistry;
import com.asen.commons.core.meta.entity.*;
import com.asen.commons.core.meta.helper.EntityFieldHelper;
import com.asen.commons.utils.SpringUtil;
import com.asen.commons.utils.StringUtils;
import io.swagger.annotations.ApiModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体表加载类
 *
 * @author ls
 * @version 1.0
 * @date 2024-04-10
 */
public class EntityObjectLoader {

    private static final Logger logger = LoggerFactory.getLogger(EntityObjectLoader.class);

    private static EntityObjectLoader loader = null;

    /**
     * 实体类 => 实体对象
     */
    private static final Map<Class<?>, EntityObject> entityMap = new HashMap<>();

    public static EntityObjectLoader getInstance() {

        if (loader == null) {
            synchronized (EntityObjectLoader.class) {
                loader = new EntityObjectLoader();
            }
        }

        return loader;
    }

    /**
     * 初始化实体属性
     *
     * @param entityClass
     */
    public EntityObject load(Class<?> entityClass) {
        if (entityClass == null) {
            return null;
        }

        EntityObject entityObject = entityMap.get(entityClass);

        if (entityObject != null) {
            return entityObject;
        }

        synchronized (entityClass) {

            //创建并缓存EntityObject
            entityObject = new EntityObject(entityClass);

            if (entityClass.isAnnotationPresent(ApiModel.class)) {
                ApiModel apiModel = entityClass.getAnnotation(ApiModel.class);
                entityObject.setAlias(apiModel.value());
            }

            if (entityClass.isAnnotationPresent(EntityModel.class)) {
                EntityModel entityTable = entityClass.getAnnotation(EntityModel.class);
                if (entityTable != null) {
                    entityObject.setEntityTable(entityTable);
                }
            }

            if (entityClass.isAnnotationPresent(QueryResultProcessor.class)) {
                QueryResultProcessor resultProcessor = entityClass.getAnnotation(QueryResultProcessor.class);
                registerProcessors(entityClass, resultProcessor.value());
            }

            if (entityObject == null) {
                entityObject = new EntityObject(entityClass);
            }

            List<EntityField> entityFieldList = EntityFieldHelper.getAllFields(entityClass);
            for (EntityField entityField : entityFieldList) {
                Field field = entityField.getField();

                //忽略static和transient字段
                if (Modifier.isStatic(field.getModifiers())
                        || Modifier.isTransient(field.getModifiers())) {
                    continue;
                }

                // 忽略集合类型
                //                if (Map.class.isAssignableFrom(entityField.getJavaType())
                //                        || Collection.class.isAssignableFrom(entityField.getJavaType())) {
                //                    continue;
                //                }

                FieldObject fieldObject = new FieldObject(entityField);

                entityObject.addFieldObject(fieldObject);

            }

            entityMap.put(entityClass, entityObject);
        }

        return entityObject;
    }

    private void registerProcessors(Class<?> entityClass, String processors) {
        if (StringUtils.isEmpty(processors)) {
            return;
        }

        String[] processorArray = processors.split(",");
        for (String processorString : processorArray) {
            try {
                ResultProcessor processor = null;

                try {
                    processor = (ResultProcessor) SpringUtil.getBean(processorString);
                } catch (Exception e) {
                    logger.error("Not a valid bean [" + processorString + "]");
                }

                if (processor == null) {
                    try {
                        processor = (ResultProcessor) Class.forName(processorString).newInstance();
                    } catch (Exception e) {
                        logger.error("Not a valid class [" + processorString + "]");
                    }
                }

                ResultProcessorRegistry.register(entityClass, processor);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    public EntityObject get(Class<?> entityClass) {
        EntityObject entityObject = entityMap.get(entityClass);

        if (entityObject == null) {
            entityObject = load(entityClass);
        }

        return entityObject;
    }

    public EntityObject load(FieldObject fo) {
        if (fo == null) {
            return null;
        }
        return load(fo.getJavaType());
    }

    public EntityObject loadByModel(Object model) {
        if (model == null) {
            return null;
        }
        return load(model.getClass());
    }
//
//    public EntityObject loadX(String modelType) {
//        try {
//            Class<?> clazz = Class.forName(modelType);
//            return load(clazz);
//        } catch (Exception e) {
//        }
//        return null;
//    }
}
